<?php

namespace app\attachment\controller;

use think\Controller;
use OSS\Core\OssException;
use OSS\OssClient;

class Oss extends Controller
{
    public $bucket_url;
    protected $config;
    protected $client;
    protected $error;

    protected function initialize()
    {
        $this->config = config('zzcms.oss_info');
        $this->client = new OssClient($this->config['key_id'], $this->config['key_secret'], $this->config['endpoint']);
        $this->bucket_url = $this->config['url'];
    }

    /**
     * 图片裁剪
     * @param $url  图片地址
     * @param $filename  保存文件名
     * @param array $param 参数  宽，高，偏移量
     * @return bool|string
     */
    public function cropsize($url, $filename, $param = [])
    {
        //裁剪宽度
        $width = isset($param['width']) ? intval($param['width']) : 100;
        //裁剪高度
        $height = isset($param['height']) ? intval($param['height']) : 100;
        //X偏移量
        $offsetx = isset($param['offsetx']) ? intval($param['offsetx']) : 0;
        //Y偏移量
        $offsety = isset($param['offsety']) ? intval($param['offsety']) : 0;
        $content = file_get_contents($url);
        $result = $this->putFile($filename, $content);
        if (!$result) {
            $this->error = $this->getError();
            return false;
        }
        return $this->saveas($filename, ['width' => $width, 'param' => "x-oss-process=image/crop,x_{$offsetx},y_{$offsety},w_{$width},h_{$height}"]);
    }

    /**
     * 站内保存
     * @param $filename
     * @param int $width
     * @return string
     */
    public function saveas($filename, $param = [])
    {
        $width = isset($param['width']) ? intval($param['width']) : 1000;

        //生成EncodedEntryURI的值
        $new_filename = str_replace('.', "_w{$width}.", $filename);
        //$image_url = "{$this->bucket_url}{$filename}?x-oss-process=image/resize,w_{$width}|sys/saveas,o_" . urlsafeBase64Encode($new_filename);
        $image_url = "{$this->bucket_url}{$filename}?{$param['param']}";
        $file = SITE_PATH . $new_filename;
        if (!downloadImage($image_url, $file)) {
            $this->error = '从OSS下载图片出错误:' . $file;
            return false;
        }
        if (!$this->upload($new_filename, $file)) {
            $this->error = '上传图片到OSS出错误:' . $file;
            return false;
        }
        return $this->bucket_url . $new_filename;
    }


    /**
     * 下载 文件
     * @param $object  文件名
     * @param $file   文件
     * @param string $param 图片处理规则
     * @return bool
     */
    public function downloadFile($object, $file, $param = '')
    {
        if (empty($param)) {
            $param = 'image/resize,m_lfit,w_1000';
        }
        $options = [
            OssClient::OSS_FILE_DOWNLOAD => $file,
            OssClient::OSS_PROCESS => $param
        ];
        //设置文件夹的权限
        $this->ckeckDir($file);
        try {
            $this->client->getObject($this->config['bucket'], $object, $options);
        } catch (OssException $e) {
            $this->error = $e->getErrorMessage();
            return false;
        }
        return true;
    }

    /**
     * 下载到本地内存
     * @param $object
     * @return bool
     */
    public function downloadMemory($object, $param = '')
    {
        if (empty($param)) {
            $param = 'image/resize,m_lfit,w_1000';
        }
        $options = [
            OssClient::OSS_PROCESS => $param
        ];
        try {
            $content = $this->client->getObject($this->config['bucket'], $object, $options);
        } catch (OssException $e) {
            $this->error = $e->getErrorMessage();
            return false;
        }
        return $content;
    }


    public function signUrl($object)
    {
        $timeout = 3600;
        $options = [
            OssClient::OSS_PROCESS => "image/resize,m_lfit,w_1000",
        ];
        return $this->client->signUrl($this->config['bucket'], $object, $timeout, "GET", $options);
    }


    /**
     * 字符串上传
     * @param $filename
     * @param $content
     * @return bool
     */
    public function getFileMeta($file)
    {
        try {
            $objectMeta = $this->client->getObjectMeta($this->config['bucket'], $file);
        } catch (OssException $e) {
            $this->error = $e->getErrorMessage();
            return false;
        }
        return empty($objectMeta) ? false : $objectMeta;
    }


    /**
     * 上传字符串
     * @param $filename
     * @param $content
     * @return bool
     */
    public function putFile($filename, $content)
    {
        try {
            $this->client->putObject($this->config['bucket'], $filename, $content);
        } catch (OssException $e) {
            $this->error = $e->getErrorMessage();
            return false;
        }
        return true;
    }


    /**
     * 上传文件到阿里云OSS
     * 说明  当cateid=1时，表示七牛图片类型
     * @param $filename   上传到七牛的名字，包含路径，最好跟本地目录结构一样
     * @param $file_path  本地文件所在地址
     * @param int $userid
     * @param int $other
     * @return bool
     */
    public function upload($filename, $file_path)
    {
        try {
            $this->client->uploadFile($this->config['bucket'], $filename, $file_path);
        } catch (OssException $e) {
            $this->error = $e->getErrorMessage();
            return false;
        }
        return true;
    }

    /**
     * 拷贝object
     * @param $filename  源文件
     * @param $newfile  新文件
     * @return bool
     */
    public function copyFile($filename, $newfile, $tobucket = '')
    {
        if (empty($tobucket)) {
            $tobucket = $this->config['bucket'];
        }
        try {
            $this->client->copyObject($this->config['bucket'], $filename, $tobucket, $newfile);
        } catch (OssException $e) {
            $this->error = $e->getErrorMessage();
            return false;
        }
        return true;
    }

    /**
     * 判断object是否存在
     * @param $object  文件名（含路径）
     * @return bool
     */
    public function fileExist($object)
    {
        try {
            $exist = $this->client->doesObjectExist($this->config['bucket'], $object);
        } catch (OssException $e) {
            $this->error = $e->getErrorMessage();
            return false;
        }
        return $exist;
    }

    /**
     * 删除object
     * @param $object
     *          单个文件或者文件数组
     *          $objects = array();
     *          $objects[] = "oss-php-sdk-test/upload-test-object-name.txt";
     *          $objects[] = "oss-php-sdk-test/upload-test-object-name.txt.copy";
     * @return bool
     */
    public function deleteFile($object)
    {
        try {
            if (is_array($object)) {
                $this->client->deleteObjects($this->config['bucket'], $object);
            } else {
                $this->client->deleteObject($this->config['bucket'], $object);
            }

        } catch (OssException $e) {
            $this->error = $e->getErrorMessage();
            return false;
        }
        return true;
    }

    /**
     * 获取bucker
     * @return mixed
     */
    public function getBucker()
    {
        return $this->config['bucket'];
    }


    /**
     * 设置OSS的bucket
     * @param $bucket
     * @return mixed
     */
    public function setBucker($bucket)
    {
        return $this->config['bucket'] = $bucket;
    }


    /**
     * 返回错误信息
     * @return mixed
     */
    public function getError()
    {
        return $this->error;
    }

    /**
     * 检测用户文件目录权限
     * @param $file
     */
    private function ckeckDir($file)
    {
        $dir_array = explode('/', $file);
        $dir = str_replace(end($dir_array), '', $file);
        if (!is_dir($dir)) {
            @mkdir($dir, 0777, true);
        }
    }

}
